﻿using System;
using System.Text;
using System.Collections;
using System.Drawing;
using System.Drawing.Printing;
using System.IO;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace Titan.FIS.SampleRecd
{
	/// <summary>
	/// 打印标签生成类
	/// </summary>
	public class TagGen
	{

		#region //设备参数索引枚举
		/// <summary>
		/// 设备参数索引枚举
		/// </summary>
		internal enum DeviceCapIndex
		{
			/// <summary>
			/// Device driver version
			/// </summary>
			DRIVERVERSION = 0,
			/// <summary>
			/// Device classification
			/// </summary>
			TECHNOLOGY = 2,
			/// <summary>
			/// Horizontal size in millimeters
			/// </summary>
			HORZSIZE = 4,
			/// <summary>
			/// Vertical size in millimeters
			/// </summary>
			VERTSIZE = 6,
			/// <summary>
			/// Horizontal width in pixels
			/// </summary>
			HORZRES = 8,
			/// <summary>
			/// Vertical height in pixels
			/// </summary>
			VERTRES = 10,
			/// <summary>
			/// Number of bits per pixel
			/// </summary>
			BITSPIXEL = 12,
			/// <summary>
			/// Number of planes
			/// </summary>
			PLANES = 14,
			/// <summary>
			/// Number of brushes the device has
			/// </summary>
			NUMBRUSHES = 16,
			/// <summary>
			/// Number of pens the device has
			/// </summary>
			NUMPENS = 18,
			/// <summary>
			/// Number of markers the device has
			/// </summary>
			NUMMARKERS = 20,
			/// <summary>
			/// Number of fonts the device has
			/// </summary>
			NUMFONTS = 22,
			/// <summary>
			/// Number of colors the device supports
			/// </summary>
			NUMCOLORS = 24,
			/// <summary>
			/// Size required for device descriptor
			/// </summary>
			PDEVICESIZE = 26,
			/// <summary>
			/// Curve capabilities
			/// </summary>
			CURVECAPS = 28,
			/// <summary>
			/// Line capabilities
			/// </summary>
			LINECAPS = 30,
			/// <summary>
			/// Polygonal capabilities
			/// </summary>
			POLYGONALCAPS = 32,
			/// <summary>
			/// Text capabilities
			/// </summary>
			TEXTCAPS = 34,
			/// <summary>
			/// Clipping capabilities
			/// </summary>
			CLIPCAPS = 36,
			/// <summary>
			/// Bitblt capabilities
			/// </summary>
			RASTERCAPS = 38,
			/// <summary>
			/// Length of the X leg
			/// </summary>
			ASPECTX = 40,
			/// <summary>
			/// Length of the Y leg
			/// </summary>
			ASPECTY = 42,
			/// <summary>
			/// Length of the hypotenuse
			/// </summary>
			ASPECTXY = 44,
			/// <summary>
			/// Shading and Blending caps
			/// </summary>
			SHADEBLENDCAPS = 45,
			/// <summary>
			/// Logical pixels inch in X
			/// </summary>
			LOGPIXELSX = 88,
			/// <summary>
			/// Logical pixels inch in Y
			/// </summary>
			LOGPIXELSY = 90,
			/// <summary>
			/// Number of entries in physical palette
			/// </summary>
			SIZEPALETTE = 104,
			/// <summary>
			/// Number of reserved entries in palette
			/// </summary>
			NUMRESERVED = 106,
			/// <summary>
			/// Actual color resolution
			/// </summary>
			COLORRES = 108,

			// Printing related DeviceCaps. These replace the appropriate Escapes
			/// <summary>
			/// Physical Width in device units
			/// </summary>
			PHYSICALWIDTH = 110,
			/// <summary>
			/// Physical Height in device units
			/// </summary>
			PHYSICALHEIGHT = 111,
			/// <summary>
			/// Physical Printable Area x margin
			/// </summary>
			PHYSICALOFFSETX = 112,
			/// <summary>
			/// Physical Printable Area y margin
			/// </summary>
			PHYSICALOFFSETY = 113,
			/// <summary>
			/// Scaling factor x
			/// </summary>
			SCALINGFACTORX = 114,
			/// <summary>
			/// Scaling factor y
			/// </summary>
			SCALINGFACTORY = 115,
			/// <summary>
			/// Current vertical refresh rate of the display device (for displays only) in Hz
			/// </summary>
			VREFRESH = 116,
			/// <summary>
			/// Horizontal width of entire desktop in pixels
			/// </summary>
			DESKTOPVERTRES = 117,
			/// <summary>
			/// Vertical height of entire desktop in pixels
			/// </summary>
			DESKTOPHORZRES = 118,
			/// <summary>
			/// Preferred blt alignment
			/// </summary>
			BLTALIGNMENT = 119
		}
		#endregion

		public const int PAPER_WIDTH = 60;//纸宽度（毫米）
		public const int PAPER_HEIGHT = 40;//纸高度（毫米）
		private const int BARCODE_WIDTH = 60;//条码宽度（毫米）
		private const int BARCODE_HEIGHT = 40;//条码高度（毫米）
		private const int MARGIN_X = 3;//页左右边距（毫米）
		private const int MARGIN_Y = 3;//页上下边距（毫米）
		private const int PADDING = 4;//空白边距（像素）
		private int _px = 96;//当前显示器的水平方向上每毫米的像素数
		private int _py = 96;//当前显示器的垂直方向上每毫米的像素数
		private int _ImgWidth = 0;
		private int _ImgHeight = 0;
		private int _BarcodeImgWidth = 0;
		private int _BarcodeImgHeight = 0;
		private int _MagrinX = 0;
		private int _MagrinY = 0;

		/// <summary>
		/// 构造函数
		/// </summary>
		internal TagGen()
		{
			//获取当前显示器的分辨率
			GetDPI(out this._px, out this._py);
			//获取指定尺寸的纸张和条码所对应的像素数
			this._BarcodeImgWidth = BARCODE_WIDTH * this._px * 10 / 254;
			this._BarcodeImgHeight = BARCODE_HEIGHT * this._py * 10 / 254;
			this._ImgWidth = PAPER_WIDTH * this._px * 10 / 254;
			this._ImgHeight = PAPER_HEIGHT * this._py * 10 / 254;
			this._MagrinX = MARGIN_X * this._px * 10 / 254;
			this._MagrinY = MARGIN_Y * this._py * 10 / 254;
		}

		/// <summary>
		/// 生成试样标签图像
		/// </summary>
		/// <param name="type">样品类型</param>
		/// <param name="sycode">样品编号</param>
		/// <returns></returns>
		internal Image GetImgASample(string sycode)
		{
			Font fntone = null;
			Font fnttwo = null;
			Font fntthree = null;
			SolidBrush brush = null;
			Pen pen = null;
			Bitmap img = null;
			Graphics g = null;
			Image imgBarcode = null;

			try
			{
				//创建绘图所需的对象，并设置质量和背景色
				Initialize(sycode, 10, ref img, ref imgBarcode, ref fntone, ref brush, ref pen, ref g);
				fntone = new Font("宋体", 20, FontStyle.Regular);
				fnttwo = new Font("宋体", 30, FontStyle.Regular);
				fntthree = new Font("细黑", 20, FontStyle.Regular);
				int x = 0, y = 0, w = 0, h = 0;
				Rectangle[] rects = new Rectangle[1];
				for (int i = 0; i < rects.Length; i++)
				{
					//if (i == 0)
					//{
					//    rects[i] = this.DrawImgInRect(
					//        -30,
					//        5,
					//        277,
					//        40,
					//        g, imgBarcode);
					//}
					if (i == 0)
					{
						x = 25; y = 15; w = 250; h = 100;
						rects[i] = DrawTxtInRect(
							x,
							y,
							w,
							h,
							g, fntone, brush, sycode, false, false);
					}
					//if (i == 2)
					//{
					//    x = 155; y = 100; w = 40; h = 30;
					//    rects[i] = DrawTxtInRect(
					//        x,
					//        y,
					//        w,
					//        h,
					//        g, fnttwo, brush, type, false, false);
					//}
				}
			}
			catch (Exception ex)
			{
			}
			finally
			{
				if (fntone != null)
				{
					fntone.Dispose();
				}
				if (fnttwo != null)
				{
					fnttwo.Dispose();
				}
				if (brush != null)
				{
					brush.Dispose();
				}
				if (pen != null)
				{
					pen.Dispose();
				}
				if (imgBarcode != null)
				{
					imgBarcode.Dispose();
				}
				if (g != null)
				{
					g.Dispose();
				}
			}
			return img;
		}

		/// <summary>
		/// 生成试样标签图像
		/// </summary>
		/// <param name="type">样品类型</param>
		/// <param name="sycode">样品编号</param>
		/// <returns></returns>
		internal Image GetImgASample(string sycode, string batchCode)
		{
			Font fntone = null;
			Font fnttwo = null;
			Font fntthree = null;
			SolidBrush brush = null;
			Pen pen = null;
			Bitmap img = null;
			Graphics g = null;
			Image imgBarcode = null;

			try
			{
				//创建绘图所需的对象，并设置质量和背景色
				Initialize(sycode, 10, ref img, ref imgBarcode, ref fntone, ref brush, ref pen, ref g);
				fntone = new Font("宋体", 20, FontStyle.Regular);
				fnttwo = new Font("宋体", 30, FontStyle.Regular);
				fntthree = new Font("细黑", 20, FontStyle.Regular);
				int x = 0, y = 0, w = 0, h = 0;
				Rectangle[] rects = new Rectangle[2];
				for (int i = 0; i < rects.Length; i++)
				{
					//if (i == 0)
					//{
					//    rects[i] = this.DrawImgInRect(
					//        -30,
					//        5,
					//        277,
					//        40,
					//        g, imgBarcode);
					//}
					if (i == 0)
					{
						x = 23; y = 15; w = 200; h = 100;
						rects[i] = DrawTxtInRect(
							x,
							y,
							w,
							h,
							g, fntone, brush, sycode, false, false);
					}
					if (i == 1)
					{
						x = 43; y = 55; w = 200; h = 100;
						rects[i] = DrawTxtInRect(
							x,
							y,
							w,
							h,
							g, fntone, brush, batchCode, false, false);
					}
					//if (i == 2)
					//{
					//    x = 155; y = 100; w = 40; h = 30;
					//    rects[i] = DrawTxtInRect(
					//        x,
					//        y,
					//        w,
					//        h,
					//        g, fnttwo, brush, type, false, false);
					//}
				}
			}
			catch (Exception ex)
			{
			}
			finally
			{
				if (fntone != null)
				{
					fntone.Dispose();
				}
				if (fnttwo != null)
				{
					fnttwo.Dispose();
				}
				if (brush != null)
				{
					brush.Dispose();
				}
				if (pen != null)
				{
					pen.Dispose();
				}
				if (imgBarcode != null)
				{
					imgBarcode.Dispose();
				}
				if (g != null)
				{
					g.Dispose();
				}
			}
			return img;
		}
		/// <summary>
		/// 生成试样标签图像
		/// </summary>
		/// <param name="type">样品类型</param>
		/// <param name="sycode">样品编号</param>
		/// <returns></returns>
		internal Image GetImgASample(string type, string sycode, int iPrintTestCodeNum)
		{
			Font fntone = null;
			Font fnttwo = null;
			Font fntthree = null;
			SolidBrush brush = null;
			Pen pen = null;
			Bitmap img = null;
			Graphics g = null;
			Image imgBarcode = null;


			try
			{
				//创建绘图所需的对象，并设置质量和背景色
				Initialize(sycode, 10, ref img, ref imgBarcode, ref fntone, ref brush, ref pen, ref g);

				fntone = new Font("宋体", 20, FontStyle.Regular);
				fnttwo = new Font("宋体", 20, FontStyle.Regular);
				fntthree = new Font("细黑", 20, FontStyle.Regular);
				int x = 0, y = 0, w = 0, h = 0;
				Rectangle[] rects = new Rectangle[3];
				for (int i = 0; i < rects.Length; i++)
				{
					if (iPrintTestCodeNum == 1)
					{
						if (i == 0)
						{
							x = 0; y = 0; w = 215; h = 50;
							rects[i] = DrawImgInRect(
								x,
								y,
								w,
								h,
								g, imgBarcode);
						}

						//if (i == 0)
						//{
						//    rects[i] = this.DrawImgInRect(
						//        -30,
						//        5,
						//        277,
						//        40,
						//        g, imgBarcode);
						//}

						//if (i == 0)
						//{
						//    x = 15; y = 5; w = 190; h = 90;
						//    rects[i] = DrawImgInRect(
						//        x,
						//        y,
						//        w,
						//        h,
						//        g, imgBarcode);
						//}

						if (i == 1)
						{
							x = 45; y = 102; w = 150; h = 30;
							rects[i] = DrawTxtInRect(
								x,
								y,
								w,
								h,
								g, fnttwo, brush, sycode, false, false);
						}
						//if (i == 2)
						//{
						//    x = 155; y = 100; w = 40; h = 30;
						//    rects[i] = DrawTxtInRect(
						//        x,
						//        y,
						//        w,
						//        h,
						//        g, fnttwo, brush, type, false, false);
						//}
					}
					else
					{
						if (i == 0)
						{
							x = 0; y = 0; w = imgBarcode.Width; h = imgBarcode.Height;
							rects[i] = DrawImgInRect(
								x,
								y,
								w,
								h,
								g, imgBarcode);
						}
					}
				}
			}
			catch (Exception ex)
			{
			}
			finally
			{
				if (fntone != null)
				{
					fntone.Dispose();
				}
				if (fnttwo != null)
				{
					fnttwo.Dispose();
				}
				if (brush != null)
				{
					brush.Dispose();
				}
				if (pen != null)
				{
					pen.Dispose();
				}
				if (imgBarcode != null)
				{
					imgBarcode.Dispose();
				}
				if (g != null)
				{
					g.Dispose();
				}
			}
			return img;
		}


		/// <summary>
		/// 创建绘图所需的对象，并设置质量和背景色。
		/// </summary>
		/// <param name="g"></param>
		private void Initialize(string barcode, float fontSize,
			ref Bitmap img, ref Image imgBarcode,
			ref Font fnt, ref SolidBrush brush,
			ref Pen pen, ref Graphics g)
		{
			//创建条码图像
			imgBarcode = this.GenBarcode(barcode,
					Color.Black, Color.White,
					this._BarcodeImgWidth, this._BarcodeImgHeight);

			fnt = new Font("宋体"/*"Arial"*/, fontSize, FontStyle.Regular);
			brush = new SolidBrush(Color.Black);
			pen = new Pen(brush, 1);
			img = new Bitmap(this._ImgWidth, this._ImgHeight);
			g = Graphics.FromImage(img);

			//设置Graphics的呈现质量
			g.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
			g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High;
			g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
			g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit;
			//g.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.Default;
			//g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.Default;
			//g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.Default;
			//g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit;
			//设置背景色
			g.Clear(Color.White);
		}

		/// <summary>
		/// 生成矩形框，并在其中绘制文字
		/// </summary>
		/// <param name="rectX">矩形框左上角x坐标</param>
		/// <param name="rectY">矩形框左上角y坐标</param>
		/// <param name="rectWidth">矩形框宽度</param>
		/// <param name="rectHeight">矩形框高度</param>
		/// <param name="g">GDI+绘图图面</param>
		/// <param name="fnt">文本字体格式</param>
		/// <param name="brush">单向画笔</param>
		/// <param name="context">文本内容</param>
		/// <param name="isDirectionVertical">是否竖排文字</param>
		/// <param name="isHorizontalCenter">是否水平居中对齐</param>
		/// <returns></returns>
		private Rectangle DrawTxtInRect(int rectX, int rectY, int rectWidth, int rectHeight,
			Graphics g, Font fnt, SolidBrush brush, string context,
			bool isDirectionVertical, bool isHorizontalCenter)
		{
			Rectangle rect = new Rectangle(rectX, rectY, rectWidth, rectHeight);

			if (isDirectionVertical)
			{
				//竖排
				string tmpContext = "";
				foreach (char chr in context)
				{
					tmpContext += chr + "\r\n";
				}
				tmpContext = tmpContext.TrimEnd("\r\n".ToCharArray());

				TextRenderer.DrawText(g, tmpContext, fnt, rect, brush.Color,
						 TextFormatFlags.VerticalCenter
						 | TextFormatFlags.HorizontalCenter
						 );//| TextFormatFlags.LeftAndRightPadding);
			}
			else
			{
				//横排
				if (isHorizontalCenter)
				{
					TextRenderer.DrawText(g, context, fnt, rect, brush.Color,
						 TextFormatFlags.VerticalCenter
						 | TextFormatFlags.HorizontalCenter
						 );//| TextFormatFlags.LeftAndRightPadding);
				}
				else
				{
					TextRenderer.DrawText(g, context, fnt, rect, brush.Color,
						 TextFormatFlags.VerticalCenter
						 );//| TextFormatFlags.HorizontalCenter
						   //| TextFormatFlags.LeftAndRightPadding);
				}
			}
			return rect;
		}

		/// <summary>
		/// 生成矩形框，并在其中绘制文字（GDI+方式）
		/// </summary>
		/// <param name="rectX">矩形框左上角x坐标</param>
		/// <param name="rectY">矩形框左上角y坐标</param>
		/// <param name="rectWidth">矩形框宽度</param>
		/// <param name="rectHeight">矩形框高度</param>
		/// <param name="g">GDI+绘图图面</param>
		/// <param name="fnt">文本字体格式</param>
		/// <param name="brush">单向画笔</param>
		/// <param name="context">文本内容</param>
		/// <param name="isDirectionVertical">是否竖排文字</param>
		/// <param name="isHorizontalCenter">是否水平居中对齐</param>
		/// <returns></returns>
		private Rectangle DrawTxtInRectByGraphics(int rectX, int rectY, int rectWidth, int rectHeight,
			Graphics g, Font fnt, SolidBrush brush, string context,
			bool isDirectionVertical, bool isHorizontalCenter)
		{
			Rectangle rect = new Rectangle(rectX, rectY, rectWidth, rectHeight);
			StringFormat sf = new StringFormat();
			if (isDirectionVertical)
			{
				//竖排
				sf.Alignment = StringAlignment.Center;
				sf.LineAlignment = StringAlignment.Center;
				sf.FormatFlags = StringFormatFlags.DirectionVertical;
			}
			else
			{
				//横排
				if (isHorizontalCenter)
				{
					sf.Alignment = StringAlignment.Center;
					sf.LineAlignment = StringAlignment.Center;
				}
				else
				{
					sf.Alignment = StringAlignment.Near;
					sf.LineAlignment = StringAlignment.Center;
				}
			}
			g.DrawString(context, fnt, brush, rect, sf);
			return rect;
		}

		/// <summary>
		/// 生成矩形框，并在其中绘制图像
		/// </summary>
		/// <param name="rectX"></param>
		/// <param name="rectY"></param>
		/// <param name="rectWidth"></param>
		/// <param name="rectHeight"></param>
		/// <param name="g"></param>
		/// <param name="img"></param>
		/// <returns></returns>
		private Rectangle DrawImgInRect(int rectX, int rectY, int rectWidth, int rectHeight,
			Graphics g, Image img)
		{
			Rectangle rect = new Rectangle(rectX, rectY, rectWidth, rectHeight);

			//g.DrawImage(img,
			//    rect.Left + (rect.Width - img.Width) / 2,
			//    rect.Top + (rect.Height - img.Height) / 2);
			g.DrawImage(img,
			   rect.Left + (rect.Width - img.Width) / 2,
			   5 + (rect.Height - img.Height) / 2);
			return rect;
		}

		/// <summary>
		/// 生成条码图像
		/// </summary>
		/// <param name="context"></param>
		/// <param name="includeLable"></param>
		/// <param name="forColor"></param>
		/// <param name="backColor"></param>
		/// <param name="width"></param>
		/// <param name="height"></param>
		/// <returns></returns>
		private Image GenBarcode(string context, Color foreColor, Color backColor, int width, int height)
		{
			Image img = null;
			try
			{
				//CODE128条码内容如果少于3位，扫描枪不识别
				context = context.Length < 3 ? context.PadLeft(3, ' ') : context;
				Font ftFont = new Font("Arial", 10, FontStyle.Bold);
				img = Titan.FIS.Barcode.OneDimensionBarcode.Encode(Titan.FIS.Barcode.OneDimensionBarcodeType.CODE128, context, foreColor, backColor, width, height, false, ftFont);

				//string encVal = bar.EncodedValue;
			}
			catch
			{
			}
			return img;
		}

		/// <summary>
		/// 检索指定设备的指定参数信息
		/// </summary>
		/// <param name="hdc">设备句柄</param>
		/// <param name="index">设备参数索引号</param>
		/// <returns></returns>
		[DllImport("gdi32.dll")]
		private static extern int GetDeviceCaps(IntPtr hdc, int index);

		/// <summary>
		/// 获取当前显示器设备的水平和垂直方向上每英寸的像素数
		/// </summary>
		/// <param name="px">水平方向每英寸的像素数</param>
		/// <param name="py">垂直方向每英寸的像素数</param>
		public static void GetDPI(out int px, out int py)
		{
			px = py = 0;
			Image img = null;
			Graphics g = null;
			IntPtr hdc = IntPtr.Zero;

			try
			{
				img = new Bitmap(1, 1);
				g = Graphics.FromImage(img);
				hdc = g.GetHdc();

				px = GetDeviceCaps(hdc, (int)DeviceCapIndex.LOGPIXELSX);//设备水平方向每英寸的像素数
				py = GetDeviceCaps(hdc, (int)DeviceCapIndex.LOGPIXELSY);//设备垂直方向每英寸的像素数
			}
			catch
			{
			}
			finally
			{
				if (g != null && hdc != IntPtr.Zero)
				{
					g.ReleaseHdc(hdc);
				}
				if (g != null)
				{
					g.Dispose();
				}
				if (img != null)
				{
					img.Dispose();
				}
			}
		}
	}
}
